#ifndef CLONE_DETECT_H
#define CLONE_DETECT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>

/********************* macros *********************/
#define MAX_LINE 1024
#define MAX_LEN 1024
#define SRC_FILE_NUM 2
#define MAX_FILE_NAME_LEN 255
#define MAX_DETAIL_FOR_EACH_RESULT 100
#define MAX_RESULTS 3

#define ERROR( fmt, arg ... ) \
    do{ printf("\033[35m[ERROR]\033[0m "fmt , ##arg ); }while( 0 );
#define DEBUG( fmt, arg ... ) \
    do{ if( global_options.verbose ) printf("\033[33m[DEBUG]\033[0m "fmt ,##arg ); }while( 0 );


/* ********************data types *********************/
typedef struct
{
    unsigned int  min_dup_line;
    char json_file[MAX_FILE_NAME_LEN];
    char dir[MAX_FILE_NAME_LEN];
    bool verbose;
    bool ignore_comments;
    bool ignore_braces;
    bool json_output;
}options_t;


typedef struct
{
    unsigned int line_no;
    char line[MAX_LEN];
}line_content_t;

typedef struct
{
    char file_name[MAX_FILE_NAME_LEN];
    unsigned int simplify_line_no;
    line_content_t file_content[MAX_LINE];
}src_file_t;

typedef struct
{
    unsigned int file_num;
    src_file_t src_file[ SRC_FILE_NUM ];
}src_file_list_t;

typedef struct
{
    unsigned int src_startpoint;
    unsigned int src_startpoint2;
    unsigned int length1;
    unsigned int length2;
}dup_detail_t;

typedef struct
{
    char *src1_name;
    char *src2_name;
    unsigned int dup_line;
    unsigned int dup_detail_num;
    dup_detail_t details[ MAX_DETAIL_FOR_EACH_RESULT ];
}result_t;

typedef struct
{
    unsigned int total_line;
    unsigned int result_num;
    result_t results[ MAX_RESULTS ];
}duplicate_result_t;

extern options_t global_options;
extern duplicate_result_t dup_result;

/********************* declations *********************/
extern bool record( src_file_t *src1, src_file_t *src2, unsigned int src1_start, unsigned int src1_end, unsigned int src2_start, unsigned int src2_end );
void dump_file( src_file_t *src_file );
void print_match_matrix( bool *match_matrix , unsigned int n, unsigned int m );
extern unsigned int read_dir( char * dir_name , src_file_list_t *src_file_list );
extern bool process_file( src_file_t *src_file );
extern bool find_dup_len( bool *match_matrix , src_file_t *src1, src_file_t *src2 , unsigned int i, unsigned int j );
extern bool check_match_matrix( bool *match_matrix , src_file_t *src1, src_file_t *src2 );
extern bool detect_between_files( src_file_t *src1, src_file_t *src2 );
extern bool json_output( void );
extern void output_result( void );
void clone_detect( src_file_list_t *src_file_list);
extern bool read_args( int argc, char *argv[] );
#endif
